#include "virtio-internal.h"

#include <virtio/virtio.h>

#include <types.h>
#include <core/event.h>
#include <log.h>
#include <malloc.h>

void virtio_input_config_select(volatile struct virtio_input_config *config, enum virtio_input_config_select select, int subsel)
{
    __sync_synchronize();
    config->select = select;
    config->subsel = subsel;
    __sync_synchronize();
}

void virtio_input_config_supported(volatile struct virtio_input_config *config)
{
    for (int i = 0; i < config->size * 8; i++)
    {
        if (config->u.bitmap[i / 8] & (1 << i % 8))
        {
            LOGI("support:", $(i));
        }
    }
}

void virtio_input_check_if_support(volatile struct virtio_input_config *config,
                                   enum virtio_input_config_select select, int subsel,
                                   uint list[], size_t len)
{
    virtio_input_config_select(config, select, subsel);
    virtio_input_config_supported(config);

    for (int i = 0; i < len; i++)
    {
        uint code = list[i];
        if (!(config->u.bitmap[code / 8] & (1 << code % 8)))
            PANIC("not supported:" $(code));
    }
}

void virtio_input_request_event(struct virtio_mmio_desc_t *desc, struct virtio_queue_t *data)
{
    while (1)
    {
        struct virtio_input_event *event = calloc(1, sizeof(struct virtio_input_event));
        if (!virtio_send_command_1(data, VRING_DESC(event)))
            return;
        virtio_mmio_notify(desc);
    }
}